package cn.mujiankeji.mbrowser.功能.浏览框

import android.graphics.Bitmap
import android.graphics.Canvas
import android.view.View
import android.webkit.WebResourceRequest
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.core.view.drawToBitmap
import cn.mujiankeji.mbrowser.功能.浏览框.webview.MWebView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.UUID
import androidx.core.graphics.createBitmap
import com.blankj.utilcode.util.ColorUtils
import androidx.core.graphics.get
import cn.mujiankeji.mbrowser.app.应用接口
import cn.mujiankeji.mbrowser.功能.浏览框.模型.浏览框功能枚举
import cn.mujiankeji.mbrowser.功能.浏览框.模型.浏览框页面配置
import cn.mujiankeji.mbrowser.工具.操作.IPUtils
import cn.mujiankeji.mbrowser.功能.浏览框.模型.浏览框脚本信息
import cn.mujiankeji.mbrowser.功能.浏览框.模型.网络文件信息
import cn.mujiankeji.mbrowser.工具.mlog
import com.blankj.utilcode.util.ResourceUtils
import okio.Path
import org.jsoup.Jsoup
import 操作.工具类.left
import 操作.工具类.right
import 操作.工具类.文本操作
import java.io.File


// 注意配置coroutine
/**
 * @param uuid 若在网页单例中使用，应使用网页标签页的 uuid
 * @param 浏览框创建完毕 返回true则自动加载
 * @param 响应初始化完毕 -- 界面初始化完毕
 * @param 响应加载新的页面 @return true 用户自行处理加载，false 覆盖当前页面进行加载
 * @param 响应可否加载文件 返回true可加载，返回false 不可加载 （可进行过滤拦截处理）
 * @param 响应获取加载日记 浏览框本身不记录日记，需要外部实现，无需求就不记录
 * @param 响应销毁页面 页面请求关闭
 * @param 响应确认框 返回 true 为确认， false 为否认或取消
 */
class 浏览框状态(
    var 页面配置 : 浏览框页面配置,
    val uuid : String = UUID.randomUUID().toString(),
    val 浏览框创建完毕 : ()->Boolean = {true},
    val 响应状态更新 : (状态 : 浏览框加载状态)->Unit,
    val 响应加载新的页面 : ((String) -> Boolean)?=null,
    val 响应可否加载文件 : (地址 : String, 协议头 : Map<String,String>?) -> Boolean,
    val 响应获取加载日记 : ()->List<网络文件信息>,
    val 响应下载 : ((url: String, userAgent: String?, contentDisposition: String?, mimetype: String?, contentLength: Long)->Unit)?=null,
    val 响应边缘颜色变化 :( (顶部 : Int?,底部 : Int?) -> Unit) ?= null,
    val 响应输入框 : ((信息 : String, 默认值 : String, 响应 : (String?)->Unit)->Unit)?=null,
    val 响应确认框 : ((信息 : String,响应 : (Boolean)->Unit) -> Unit) ?= null,
    val 响应安装扩展或脚本 : ((代码或地址 : String) -> Unit) ?= null,
    val 响应销毁页面 : ()->Unit,
    val 响应显示菜单 : ((list : List<浏览框功能枚举>) -> Unit) ?= null,
    ) {

    var webview : MWebView?= null
    var coroutine : CoroutineScope ?= null // 浏览框必须配置
    var mutex = Mutex()
    var 加载开始时间 : Long = 0L
    var 空白页面 : Boolean = false // 记录源码子元素数量

    // -- 基本配置 --
    var 启用页面内容搜索 by mutableStateOf(false)
    var 启用开发者模式 by mutableStateOf(false) // 显示审查元素（或叫开发者）模式
    var 启用元素选择器 by mutableStateOf(false) // 网页元素选择
    val 选中元素代码 = lazy { mutableStateOf("") }


    // -- 网页信息 --
    private val _标题 by lazy { MutableStateFlow("") } 
    val 标题: MutableStateFlow<String> get() = _标题
    
    private val _地址 by lazy { MutableStateFlow("") }
    val 地址: MutableStateFlow<String> get() = _地址
    
    var 状态 by mutableStateOf(浏览框加载状态.初始化)
    
    private val _加载进度 by lazy { MutableStateFlow(0) }
    val 加载进度: MutableStateFlow<Int> get() = _加载进度
    
    private val _网页异常 by lazy { MutableStateFlow(false) }
    val 网页异常: MutableStateFlow<Boolean> get() = _网页异常
    
    private val _启用的脚本 by lazy { MutableStateFlow<MutableList<浏览框脚本信息>>(ArrayList()) }
    val 启用的脚本: MutableStateFlow<MutableList<浏览框脚本信息>> get() = _启用的脚本
    
    var 页面iframe宽高 = 0f // 记录 iframe 宽高，过大比如有屏幕 70% 那么宽就应当标记为异常
    var 页面自动跳转次数 = 0 // 记录页面自动跳转的次数
    var 源码异常分数 = 0 // 分数越小表示越安全
    var 内容存在违规关键词 by mutableStateOf(false)
    var 是否为中国大陆IP by mutableStateOf(false)
    var 显示合规提示 by mutableStateOf(false)

    // -- 视图基本状态 --
    private val _是否暂停 by lazy { MutableStateFlow(false) }
    val 是否暂停: MutableStateFlow<Boolean> get() = _是否暂停
    
    private val _可否后退 by lazy { MutableStateFlow(false) }
    val 可否后退: MutableStateFlow<Boolean> get() = _可否后退
    
    private val _可否前进 by lazy { MutableStateFlow(false) }
    val 可否前进: MutableStateFlow<Boolean> get() = _可否前进
    
    private val _滑动到头部 by lazy { MutableStateFlow(false) }
    val 滑动到头部: MutableStateFlow<Boolean> get() = _滑动到头部

    // -- WebView 的交互内容 --
    var 翻译脚本是否已注入 : Boolean = false
    var 交互脚本是否已注入 : Boolean = false // 这是交互操作脚本
    var 油猴兼容脚本已注入 : Boolean = false // 这是油猴接口兼容脚本
    var 状态检测脚本已注入 : Boolean = false // 这是页面状态检测脚本


    // -- 控制 -- 必须先初始化后加载 --

    fun 加载(url : String, referer : String = ""){
        webview?.loadUrl(url,referer,null)
    }

    fun 重置(){
        更新加载状态(浏览框加载状态.初始化)
        空白页面 = true
        _加载进度.value = 0
        内容存在违规关键词 = false
        显示合规提示 = false
        状态检测脚本已注入 = false
        交互脚本是否已注入 = false
        油猴兼容脚本已注入 = false
        页面iframe宽高 = 0f
        页面自动跳转次数 = 0
    }

    fun 刷新(){
        coroutine?.launch {
            withContext(Dispatchers.Main){
                重置()
                webview?.reload()
                更新导航状态() // 刷新后更新导航状态
            }
        }
    }
    fun 重载(配置 : 浏览框页面配置){
        页面配置 = 配置
        刷新()
    }
    
    /**
     * 更新导航状态
     * 
     * 检查WebView的canGoBack和canGoForward状态，更新到可以后退和可以前进的Flow中
     */
    fun 更新导航状态() {
        coroutine?.launch(Dispatchers.Main) {
            webview?.let { webView ->
                _可否后退.value = webView.canGoBack()
                _可否前进.value = webView.canGoForward()
            } ?: run {
                _可否后退.value = false
                _可否前进.value = false
            }
        }
    }
    fun 暂停(){
        _是否暂停.value = true
        webview?.onPause()
    }
    fun 继续(){
        _是否暂停.value = false
        webview?.onResume()
    }
    fun 销毁(){
        重置()
        webview = null
    }

    /**
     * 翻译
     */
    fun 注入翻译脚本(){
        翻译脚本是否已注入 = true
        coroutine?.launch {
            注入脚本(ResourceUtils.readAssets2String("google/a.js"))
        }
    }

    /**
     * 保存当前页面内容到指定位置
     * 
     * @param 保存位置 保存页面文件的路径
     * @param 文件名 保存的文件名，默认为null，会使用当前页面标题作为文件名
     */
    fun 保存页面(保存位置: Path, 文件名: String? = null) {
        if (webview == null) return
        
        // 创建保存页面的协程
        coroutine?.launch {
            // 读取页面HTML内容
            webview?.evaluateJavascript("document.documentElement.outerHTML") { htmlContent ->
                try {
                    // 解码JavaScript返回的字符串（需要去除首尾引号）
                    val decodedHtml = if (htmlContent.startsWith("\"") && htmlContent.endsWith("\"")) {
                        htmlContent.substring(1, htmlContent.length - 1)
                            .replace("\\\"", "\"")
                            .replace("\\n", "\n")
                            .replace("\\r", "\r")
                            .replace("\\t", "\t")
                            .replace("\\\\", "\\")
                    } else {
                        htmlContent
                    }
                    
                    // 确定文件名
                    val 实际文件名 = 文件名 ?: run {
                        // 如果没有提供文件名，使用页面标题，并确保文件名有效
                        val 标题 = 标题.value.takeIf { it.isNotEmpty() } ?: "未命名页面"
                        标题.replace("[\\\\/:*?\"<>|]".toRegex(), "_") + ".html"
                    }
                    
                    // 处理保存路径
                    val 保存文件 = if (保存位置.toFile().isDirectory) {
                        // 如果保存位置是目录，则在目录中创建文件
                        File(保存位置.toFile(), 实际文件名)
                    } else {
                        // 否则使用指定的文件路径
                        保存位置.toFile()
                    }
                    
                    // 确保父目录存在
                    保存文件.parentFile?.mkdirs()
                    
                    // 写入文件
                    保存文件.writeText(decodedHtml)

                    应用接口.输出提示("页面已保存到: ${保存文件.absolutePath}")
                    mlog("浏览框", "页面已保存到: ${保存文件.absolutePath}")
                } catch (e: Exception) {
                    mlog("浏览框", "保存页面失败: ${e.message}", e)
                    应用接口.输出提示("保存页面失败: ${e.message}")
                }
            }
        }
    }

    fun 更新加载状态(state : 浏览框加载状态){
        if (state == 状态) return // 重复则不处理

        fun 注入基本脚本(){
            // 更新边缘颜色
            coroutine?.launch {
                更新界面边缘颜色()
            }

            // 检测页面是否空白
            coroutine?.launch {
                withContext(Dispatchers.Main) {
                    webview?.evaluateJavascript("(function(){return document.body && document.body.children.length > 0 ? 'has_content' : 'empty'})()") { result ->
                        空白页面 = result == "\"empty\"" || result == "null"
                    }
                }
            }
        }

        when(state){

            浏览框加载状态.初始化 -> {}
            浏览框加载状态.加载开始 -> {
                注入基本脚本()
                加载开始时间 = System.currentTimeMillis()
            }
            浏览框加载状态.静态元素加载完毕 -> {
                注入基本脚本()
                // 自动翻译
                if (页面配置.启用自动翻译){
                    注入翻译脚本()
                }

            }
            浏览框加载状态.加载完毕 -> {
                注入基本脚本()
                // 自动翻译
                if (页面配置.启用自动翻译){
                    注入翻译脚本()
                }

                coroutine?.launch {
                    开始检测网页合规()
                }
            }
        }

        响应状态更新(state)

        状态 = state

    }

    /**
     * 取页面上下颜色，颜色跟随效果
     */
    fun 更新界面边缘颜色() {
        if (this.webview == null || 响应边缘颜色变化 == null) return
        val v: View = this.webview as View
        if (v.height < 100) return

        var bit1 : Bitmap ?= null
        var bit2 : Bitmap ?= null

        try {
            bit1 = createBitmap(1, 1, Bitmap.Config.RGB_565)
            val c1 = Canvas(bit1)
            c1.drawColor(ColorUtils.string2Int("#ffffff"))
            v.draw(c1)
            val 顶部颜色 = bit1[0, 0]
            if (!bit1.isRecycled) bit1.recycle()

            bit2 = v.drawToBitmap(Bitmap.Config.RGB_565)
            val c = Canvas(bit2)
            c.drawColor(ColorUtils.string2Int("#ffffff"))
            v.draw(c)


            var 底部颜色 : Int ?= null
            if (bit2.height > 5){
                底部颜色 = bit2[1, bit2.height - 1]
            }
            if (!bit2.isRecycled) bit2.recycle()

            响应边缘颜色变化.invoke(顶部颜色,底部颜色)


        }catch (e : Exception){
            // e.printStackTrace()
        }
        finally {
            if (bit1?.isRecycled == false) bit1.recycle()
            if (bit2?.isRecycled == false) bit2.recycle()

        }

    }

    /**
     * 交互接收
     */
    fun 更新页面框架层大小(iframeWidth : Int,iframeHeight : Int,windowWidth : Int,windowHeight : Int){
        try {
            if (iframeWidth > windowWidth * 0.6 && iframeHeight > windowHeight * 0.6){
                页面iframe宽高 = 0.6f
            }else{
                页面iframe宽高 = iframeWidth.toFloat() / windowWidth
            }
            coroutine?.launch {
                合规性判断()
            }

        }catch (e : Exception){

        }
    }

    /**
     * @return true 用户自行处理加载，false 覆盖当前页面进行加载
     */
    fun 加载新的页面(url : String, request : WebResourceRequest?) : Boolean{
        // 若加载同个页面则本页刷新
        if (url == 地址.value || 地址.value.isEmpty()) return false

        request?.let {
            // 无手势自动跳转--不给
            if (!it.hasGesture() && !空白页面) return true

            // 重定向 本页加载
            if (request.isRedirect) return false
        }

        // 调用者路由去处理咯
        return 响应加载新的页面?.invoke(url) == true

    }


    // -- 函数 --
    var 读源码听众 : ((String)->Unit) ?= null
    fun 读源码(callback : (String)->Unit){
        读源码听众 = callback;
        webview?.evaluateJavascript("window.mbrowser.htmlCallback(document.getElementsByTagName('html')[0].innerHTML);"){

        }
    }
    suspend fun 注入脚本(script : String){
        withContext(Dispatchers.Main){
            webview?.注入脚本(script)
        }
    }

    /**
     * 主动请求更新页面状态
     * 一般页面变化时都会主动调用。
     */
    suspend fun 请求更新页面状态(){
        var js = "\ndocument.addEventListener(\"readystatechange\",function(e){window.mbrowser.readyState(document.readyState)});"
        js += "\nif(document.readyState==\"interactive\"){window.mbrowser.readyState(document.readyState)}else{if(document.readyState==\"complete\")" +
                "{window.mbrowser.readyState(document.readyState)}};"

        // 开启了电脑模式
        if (页面配置.启用电脑模式) {
            js += "\n\nvar oMeta = document.createElement('meta');oMeta.content = 'target-densitydpi=400';oMeta.name = 'viewport';document.getElementsByTagName('head')[0].appendChild(oMeta);\n\n"
        }
        webview?.注入脚本(js)

        // 基本插件
        if (!交互脚本是否已注入) {
            mutex.withLock {
                启用的脚本.value.clear()
            }
            ResourceUtils.readAssets2String("js/mbrowser.js")
                .let { 注入脚本(it) }
        }

        // 油猴扩展
        if (!油猴兼容脚本已注入){
            ResourceUtils.readAssets2String("ext/yi")
                .let { "$it\n window.webviewmxname.initend()".replace("webviewmxname", "a${uuid}") }
                .let { 注入脚本(it) }
        }

        // 可否前进后退
        更新导航状态()
    }

    fun 合规性判断(){
        // 外网IP + ( 跳转次数 >= 2 || 异常点 >=2 || a标签异常)
        var b1 = 源码异常分数
        if (页面iframe宽高 >= 0.6f) b1 = 2
        if (页面自动跳转次数 >= 2) b1 += 2
        内容存在违规关键词 = 源码异常分数 >= 6
    }


    /**
     * 判定网页是否存在不合规的可能
     */
    suspend fun 开始检测网页合规(){
        val title = 标题.value

        if (页面配置.启用内容合规检测 && !是否暂停.value && coroutine != null){

            // 检测框架
            """
            // 获取页面上所有的iframe
            var iframes = document.getElementsByTagName('iframe');
            var iframeWidth = 0
            var iframeHeight = 0
            for (var i = 0; i < iframes.length; i++) {
                var iframe = iframes[i];
        
                // 确保iframe已加载完成
                iframe.onload = function() {
                    // 获取iframe相对于视口的位置和大小
                    var iframeRect = this.getBoundingClientRect();
                    iframeWidth += iframeRect.width;
                    iframeHeight = iframeRect.height;
                    var windowWidth = window.innerWidth;  
                    var windowHeight = window.innerHeight;  
                    
                    window.mbrowser.iframeSize(iframeWidth,iframeHeight,windowWidth,windowHeight)
                };
            }
            """
                .trimIndent().let { 注入脚本(it) }



            // 检测IP。 若无法判定IP所在地，则相当于出现非法关键词 + 1异常关键词
            val ip = IPUtils.getIP(文本操作.取地址主机(地址.value)?:"")


            if (ip == null) 源码异常分数 += 1
            else {
                // 局域网ip直接不管
                listOf("10.","172.","192.168.","fe8","fc0","fec").forEach {
                    if (ip.startsWith(it)) {
                        是否为中国大陆IP = false
                        显示合规提示 = false
                        return
                    }
                }
                IPUtils.是否为中国大陆IP段(ip).let {
                    是否为中国大陆IP = it
                }
            }

            // 非大陆IP
            if (!是否为中国大陆IP) 源码异常分数 += 1

            // 域名为IP，且若IP所在外网，kx+1
            if (文本操作.取地址主机(地址.value).contains(Regex("[0-9]+.[0-9]+.[0-9]+.[0-9]+"))) {
                if (是否为中国大陆IP) 源码异常分数+=1
                else 源码异常分数+=2
            }

            读源码 {
                    code->

                val url = 地址.value

                // 匹配到关键词
                val el = Jsoup.parse(code).body()
                val zw = el.text().toString() // 正文

                // 若出现备案字样且服务器在中国内地，则容错 -5
                if (zw.contains("ICP备",true) && 是否为中国大陆IP){
                    源码异常分数 -= 5
                }

                // 无内容但a链接很多，除非导航网站，应为首页。否则a链接不应该过多，且要满足这并非首页 +1
                if (zw.length < 100 && !url.endsWith("/")){
                    el.getElementsByTag("a").size.let { size->
                        var a标签异常 = false
                        if (zw.isEmpty() && size > 1) a标签异常 = true
                        else if (size > 2 && zw.length > 1){
                            a标签异常 = (size / zw.length) < 10
                        }

                        if (a标签异常){
                            源码异常分数++
                        }
                    }
                }

                // 带端口号  异常 + 3(内地地址+2)
                url.right("://")?.let {
                    (it.left("/") ?: it).contains(Regex(":\\d+$")).let {it2->
                        if (it2) {
                            源码异常分数 += if (!是否为中国大陆IP) 3 else 2
                        }

                    }
                }

                // 匹配关键词数
                var kz = 0

                val s = StringBuilder()
                code.forEach {
                    if (it.code > 文本操作.正则中文起始符()) s.append(it.toString())
                }

                val a2 = listOf("六合彩","百家樂","輪盤","彩票","棋牌","百家乐","线上娱乐","时时彩","发牌","充值","威尼斯人","真人","荷官","葡京"
                    ,"母狗","乱抡","反差","无码","三级","开元棋牌","抢庄牛牛","SM另类","午夜福利","少妇","暖交","同城约炮","另类小说"
                    ,"另类变态","另类图片","欧美性爱","自拍偷拍","亚洲AV","调教","学生嫩妹","制服诱惑","强奸乱抡","日本伦理","萝莉少女","抖阴视频","国产情侣"
                    ,"人妻无码","国模私拍","中文无码","SM重味","日本无码","麻豆","取款","存款","娱乐","免费毛片","开源官方","高潮","免费X站","破解福利"
                    ,"羞羞视频","如意直播","杏花色","月季色播","草榴社区","小姐服务","萝莉禁漫","暗网精选","暗网禁地","骚女","幼幼","人兽","幼女","海角","91猎奇"
                    ,"父女乱抡","国产精选","幼幼仓库","百合萝莉","恋人黄播","熟女教师","乱伦视频","乱伦精选","强奸调教","成人天堂","金沙澳门","格格导航","草莓色漫","成人资源"
                    ,"杏吧","成人抖阴")
                a2.forEach { t3->
                    if (s.contains(t3)){
                        kz++
                    }
                }

                // 在以上关键词下再出现以下字样，关键词 + 3
                if (kz > 0) {
                    val a1 = listOf("澳門", "越南", "菲律宾", "永久域名", "永久网址")
                    a1.forEach { t2 ->
                        if (code.contains(t2)) kz += 5
                    }
                }

                // 关键词 1 : 120 算正常
                if (s.length > 100 && kz > 1){
                    (s.length - (kz * 50)).let { it ->
                        if ( it > 0) kz = 0
                    }


                }

                源码异常分数 += if (kz == 0) 0
                else kz / 2

                // 网站无内容，但标题出现以下关键词 +2
                if (zw.length < 80){
                    for (s in listOf("体育", "欧洲", "澳门","葡京","联赛","体育","冠军","金牌","体彩","足球","棋牌","百家乐","真人","荷官")) {
                        if (title.contains(s)){
                            源码异常分数 += 2
                        }
                    }
                }


                // 搜索进入，没有一条内容，十有八九有问题 或者标题就是地址， +3
                if (页面配置.是否为搜索进入页 && code.length > 123 && zw.length < 10){
                    源码异常分数 += 3

                    // 地址就是标题很多都有问题
                    if (url.contains(title)) 源码异常分数 += 5
                }

                // 尝试读取
                if (页面iframe宽高 == 0f){
                    var iframew = 0f
                    var iframeh = 0f
                    el.getElementsByTag("iframe").forEach {
                        it.attr("width").let {
                            if (it.endsWith("%")){
                                it.substring(0,it.length - 1).let {
                                    try {
                                        iframew += it.toInt().toFloat() / 100
                                    }catch (e : Exception){
                                        e.printStackTrace()
                                    }
                                }
                            }
                            else{
                                it.toIntOrNull()?.let {
                                    iframew += (it / 450).toFloat()
                                }
                            }
                        }
                        it.attr("height").let {
                            if (it.endsWith("%")){
                                it.substring(0,it.length - 1).let {
                                    try {
                                        iframeh += it.toInt().toFloat() / 100
                                    }catch (e : Exception){
                                        e.printStackTrace()
                                    }
                                }
                            }else{
                                it.toIntOrNull()?.let {
                                    iframeh += (it / 450).toFloat()
                                }
                            }
                        }

                    }

                    if ((iframew > 0.6f && iframeh > 0.5f) || (iframeh > 0.6f && iframew > 0.5f)){
                        页面iframe宽高 = 0.8f
                    }

                }

                coroutine?.launch {
                    合规性判断()
                }
            }

        }
    }

    // -- 页面内容搜索相关函数 --
    
    /**
     * 执行页面内容搜索
     * @param 搜索文本 要搜索的文本
     * @param 向下搜索 true表示向下搜索，false表示向上搜索
     */
    fun 执行页面内容搜索(搜索文本: String,向下搜索 : Boolean = true) {
        if (搜索文本.isBlank()) return
        if (webview != null) {
            if (向下搜索) {
                // 首次搜索或向下搜索
                webview?.findAllAsync(搜索文本)
            } else {
                // 向上搜索
                webview?.findNext(false)
            }
        }
    }
    
    /**
     * 关闭页面内容搜索
     */
    fun 关闭页面内容搜索() {
        webview?.clearMatches()
        启用页面内容搜索 = false
    }

    /**
     * 切换元素审查模式
     */
    fun 开启开发者工具() {
        coroutine?.launch {
            if (!交互脚本是否已注入){
                请求更新页面状态()
            }
            启用开发者模式 = true
            设置元素选择器启用状态(true)
        }
    }

    /**
     * 关闭元素审查工具
     */
    fun 关闭开发者工具() {
        coroutine?.launch {
            启用开发者模式 = false
            设置元素选择器启用状态(false)
        }
    }
    suspend fun 设置元素选择器启用状态(启用 :Boolean){
        if (启用) {
            webview?.let { view ->
                // 启用元素审查
                注入脚本("m_enable_elementdebug(true)")

                // 使用WebView类中的最后点击位置选择元素
                // 如果没有有效的点击位置，则使用屏幕中心位置
                val x = if (view.nDownX > 0) view.nDownX.toInt() else view.width / 2
                val y = if (view.nDownY > 0) view.nDownY.toInt() else view.height / 2
                注入脚本("t_sel_start_element(document.elementFromPoint($x,$y))")
            }
            启用元素选择器 = true
        }
        else
        {
            启用元素选择器 = false
            注入脚本("m_enable_elementdebug(false)")
        }

    }

}